import java.util.EmptyStackException;
import java.util.Stack;
import java.util.StringTokenizer;

class MyDC extends calcArithmatic{

    private Stack<String> stack;
    private String mod;
    MyDC(String mod){
        stack = new Stack<>();
        this.mod=mod;
    }

    String calculate(String expr) throws ExprFormatException{
        String op1,op2;
        String result;
        String token;
        StringTokenizer tokenizer = new StringTokenizer(expr);
        while (tokenizer.hasMoreTokens()){
            token=tokenizer.nextToken();
            if(isOperator(token)){
                try{
                    op2=stack.pop();
                    op1=stack.pop();
                } catch (EmptyStackException e){
                    throw new ExprFormatException("Format Error");
                }

                if (isOperator(op1) || isOperator(op2)) {
                    throw new ExprFormatException("Format Error");
                }
                result=calcSingle(op1,op2,token,mod);
                stack.push(result);
            } else {
                stack.push(token);
            }
        }
        result=stack.pop();
        if (!stack.empty()){
            throw new ExprFormatException("Format Error");
        }
        return result;
    }

    private static int gcd(int x, int y){
        int temp;
        if (x<0){
            x*=-1;
        }
        if (y<0){
            y*=-1;
        }
        if (x<y) {
            temp = x;
            x = y;
            y = temp;
        }
        while (y!=0){
            temp=x%y;
            x=y;
            y=temp;
        }
        return x;
    }

    private String calcSingle(String op1, String op2, String operation,String mod){
        String result = "";
        if (mod.equals("Rational")){
            double numResult,numOp1=Double.parseDouble(op1),numOp2=Double.parseDouble(op2);
            switch (operation){
                case "+":
                    numResult=numOp1+numOp2;
                    break;
                case "-":
                    numResult=numOp1-numOp2;
                    break;
                case "×":
                    numResult=numOp1*numOp2;
                    break;
                case "÷":
                    numResult=numOp1/numOp2;
                    break;
                default:
                    numResult=0;
            }
            result=String.valueOf(numResult);
        }else if (mod.equals("Fraction")){
            int dominator1=1,numerator1;//0/1
            int dominator2=1, numerator2;
            int dominator=1,numerator=0;
            if (op1.matches(".*/.*")){
                dominator1=Integer.valueOf(op1.split("/")[1]);
                numerator1=Integer.valueOf(op1.split("/")[0]);
            } else {
                numerator1=Integer.valueOf(op1);
            }
            if (op2.matches(".*/.*")){
                dominator2=Integer.valueOf(op2.split("/")[1]);
                numerator2=Integer.valueOf(op2.split("/")[0]);
            } else {
                numerator2=Integer.valueOf(op2);
            }
            switch (operation){
                case "+":
                    numerator=numerator1*dominator2+numerator2*dominator1;
                    dominator=dominator1*dominator2;
                    break;
                case "-":
                    numerator=numerator1*dominator2-numerator2*dominator1;
                    dominator=dominator1*dominator2;
                    break;
                case "×":
                    numerator=numerator1*numerator2;
                    dominator=dominator1*dominator2;
                    break;
                case "÷":
                    numerator=numerator1*dominator2;
                    dominator=numerator2*dominator1;
                    break;
                default:
            }
            if(0==dominator){
                throw new ArithmeticException();
            }
            int gcdivisor = gcd(numerator,dominator);
            if (dominator/gcdivisor!=1) {
                if (dominator<0){
                    dominator*=-1;
                    numerator*=-1;
                }
                result = result + numerator / gcdivisor + '/' + dominator / gcdivisor;
            }
            else {
                result = result + numerator / gcdivisor;
            }
        }
        return result;
    }
}
